# encoding: utf-8
"""
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    created by lane.chang on '17/10/2024'
    comment: 自定义页面
"""
from fastapi import APIRouter, Request, Body, Query

from config import Config
from project.core.exception import NoRecordError, BizError
from project.core.function import json_response
from project.lib.common import Global
from project.lib.decorator import api_common, exec_duration
from project.lib.constant import DEFAULT_VALUE
from project.model.database.basic import Component
from project.model.database.flow import FlowPage
from project.model.basic import PageType
from project.service.flow import FlowService


page_router = APIRouter(prefix='/m', tags=['manager.page'])


@page_router.post('/flow/page/add', summary='新增页面')
@api_common(doc_replace=(('{0}', Config.ENV_DOC_FIX),), verify_login=True)
@exec_duration(add_return=True)
async def do_flow_page_add(request: Request,
                           page_type: PageType.enums(fixed=Global.count()) = Body(..., title='页面类型', description='common(普通)/work_order(工单)'),
                           flow_role_id: int = Body(..., title='流程角色id'),
                           flow_process_id: int = Body(..., title='流程状态id'),
                           component_id: int = Body(..., title='组件id'),
                           session=None,
                           body_params=None):
    """
    **desc**: 新增页面

    **url**: http(s)://{0}.udicaria.com/m/flow/page/add

    **method**: POST

    **params**:

        <body>:
            page_type: 页面类型
            flow_role_id: 流程角色id
            flow_process_id: 流程状态id
            component_id: 组件id

    **return**:json数据结构::

        {
            code: 0(成功)/非0(失败)
            message: 成功返回success, 否则返回error信息
            data:
            exec_time: 接口后端处理时长
        }
    """
    flow_page = await FlowService.do_page_add(session, body_params)

    return json_response(data=flow_page.dict('id') if flow_page else {})


@page_router.post('/flow/page/update', summary='修改页面')
@api_common(doc_replace=(('{0}', Config.ENV_DOC_FIX),), verify_login=True)
@exec_duration(add_return=True)
async def do_flow_page_update(request: Request,
                              id: int = Body(..., title='流程页面id'),
                              title: str = Body(DEFAULT_VALUE, max_length=30, title='页面组件标题'),
                              content: str = Body(DEFAULT_VALUE, max_length=200, title='页面组件文案'),
                              remark: str = Body(DEFAULT_VALUE, max_length=200, title='备注信息'),
                              rate: int = Body(100, title='页面组件比例'),
                              style: str = Body(DEFAULT_VALUE, title='页面组件样式'),
                              items: list = Body(DEFAULT_VALUE, title='页面组件显示的值列表'),
                              to_flow_process_id: int = Body(DEFAULT_VALUE, title='目标服务流程状态id'),
                              session=None,
                              body_params=None):
    """
    **desc**: 修改页面

    **url**: http(s)://{0}.udicaria.com/m/flow/page/update

    **method**: POST

    **params**:

        <body>:
            id: 流程页面id
            title: 页面组件标题
            content: 页面组件文案
            remark: 页面组件备注信息
            rate: 页面组件比例
            style: 页面组件样式
            items: 页面组件显示的值列表
            to_flow_process_id: 目标服务流程状态id

    **return**:json数据结构::

        {
            code: 0(成功)/非0(失败)
            message: 成功返回success, 否则返回error信息
            data:
            exec_time: 接口后端处理时长
        }
    """
    try:
        await FlowPage.create_modify(session,
                                     wheres=(FlowPage.id == id),
                                     **body_params.dict(),
                                     no_record_error=True)
    except NoRecordError:
        raise BizError('角色页面不存在')

    return json_response()


@page_router.get('/flow/page/detail', summary='页面详情')
@api_common(doc_replace=(('{0}', Config.ENV_DOC_FIX),), verify_login=True)
@exec_duration(add_return=True)
async def get_flow_page_detail(request: Request,
                               id: int = Query(0, title='页面id'),
                               flow_role_id: int = Query(0, title='流程角色id'),
                               flow_process_id: int = Query(0, title='流程状态id'),
                               session=None):
    """
    **desc**: 自定义页面详情（可通过页面id查询 或 角色id与状态id组合查询）

    **url**: http(s)://{0}.udicaria.com/m/flow/page/detail

    **method**: GET

    **params**:

        <query>:
            id: 流程角色id
            flow_role_id: 流程角色id
            flow_process_id: 流程状态id

    **return**:json数据结构::

        {
            code: 0(成功)/非0(失败)
            message: 成功返回success, 否则返回error信息
            data: {
                page_type: 页面类型
                flow_id: 服务流程id
                flow_code: 服务流程编号
                flow_role_id: 流程角色id
                flow_process_id: 服务流程状态id
                component_id: 组件id
                component: 组件信息
                title: 组件标题
                content: 组件文案
                remark: 备注信息
                rate: 组件比例
                items: 组件显示的值列表
                to_flow_process_id: 目标服务流程状态id
                rank: 排序
            }
            exec_time: 接口后端处理时长
        }
    """
    if id:
        flow_page = await FlowPage.fetch_one(session, wheres=(FlowPage.id == id))
    elif flow_role_id and flow_process_id:
        flow_page = await FlowPage.fetch_one(session, wheres=(FlowPage.flow_role_id == flow_role_id, FlowPage.flow_process_id == flow_process_id))
    else:
        return json_response()
    if not flow_page:
        return json_response()

    ret_data = flow_page.dict()
    # 组件信息
    component = await Component.fetch_one(session, wheres=(Component.id == flow_page.component_id))
    ret_data['component'] = component.dict() if component else {}

    return json_response(data=ret_data)


@page_router.get('/flow/page/list', summary='页面列表')
@api_common(doc_replace=(('{0}', Config.ENV_DOC_FIX),), verify_login=True)
@exec_duration(add_return=True)
async def get_flow_page_list(request: Request,
                             flow_role_id: int = Query(..., title='流程角色id'),
                             session=None,
                             body_params=None):
    """
    **desc**: 角色页面列表

    **url**: http(s)://{0}.udicaria.com/m/flow/page/list

    **method**: GET

    **params**:

        <body>:
            flow_role_id: 流程角色id

    **return**:json数据结构::

        {
            code: 0(成功)/非0(失败)
            message: 成功返回success, 否则返回error信息
            data: [
                {
                    page_type: 页面类型
                    flow_id: 服务流程id
                    flow_code: 服务流程编号
                    flow_role_id: 流程角色id
                    flow_process_id: 服务流程状态id
                    component_id: 组件id
                    component: 组件信息
                    title: 组件标题
                    content: 组件文案
                    remark: 备注信息
                    rate: 组件比例
                    style: 组件样式
                    items: 组件显示的值列表
                    to_flow_process_id: 目标服务流程状态id
                    rank: 排序
                }
            ]
            exec_time: 接口后端处理时长
        }
    """
    data = await FlowPage.fetch_all(session, wheres=(FlowPage.flow_role_id == flow_role_id, ~FlowPage.is_deleted), orders=(FlowPage.rank,))

    # 组件信息
    component_ids = [v.component_id for v in data]
    components = await Component.fetch_all(session, wheres=(Component.id.in_(component_ids)))
    component_map = {v.id: v for v in components}

    items = []
    for v in data:
        d = v.dict()
        component = component_map.get(v.component_id)
        d['component'] = component.dict() if component else {}

        items.append(d)

    return json_response(data=items)


@page_router.post('/flow/page/delete', summary='删除页面')
@api_common(doc_replace=(('{0}', Config.ENV_DOC_FIX),), verify_login=True)
@exec_duration(add_return=True)
async def do_flow_page_delete(request: Request,
                              id: int = Body(..., title='流程页面id', embed=True),
                              session=None):
    """
    **desc**: 删除页面

    **url**: http(s)://{0}.udicaria.com/m/flow/page/delete

    **method**: POST

    **params**:

        <body>:
            id: 角色页面id

    **return**:json数据结构::

        {
            code: 0(成功)/非0(失败)
            message: 成功返回success, 否则返回error信息
            data:
            exec_time: 接口后端处理时长
        }
    """
    try:
        await FlowPage.create_modify(session,
                                     wheres=(FlowPage.id == id),
                                     is_deleted=1,
                                     no_record_error=True)
    except NoRecordError:
        raise BizError('角色页面不存在')

    return json_response()


@page_router.post('/flow/page/order', summary='页面排序')
@api_common(doc_replace=(('{0}', Config.ENV_DOC_FIX),), verify_login=True)
@exec_duration(add_return=True)
async def do_flow_page_order(request: Request,
                             ids: list[int] = Body(..., title='角色页面id列表', embed=True),
                             session=None):
    """
    **desc**: 页面排序

    **url**: http(s)://{0}.udicaria.com/m/flow/page/order

    **method**: POST

    **params**:

        <body>:
            ids: 角色页面id列表

    **return**:json数据结构::

        {
            code: 0(成功)/非0(失败)
            message: 成功返回success, 否则返回error信息
            data:
            exec_time: 接口后端处理时长
        }
    """
    for idx, flow_page_id in enumerate(ids):
        # no_to_create=False 如果碰到检索不到的情况，不会创建新记录
        await FlowPage.create_modify(session, wheres=(FlowPage.id == flow_page_id), rank=idx, no_to_create=False)

    return json_response()
